﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Tools
{
    public class ExceptionHelper
    {
        #region CODES
        
        //"Argument '{0}' in method '{1}' can not be empty";
        public const string excode_empty_argument = "excode_empty_argument";
        //"Exception was appeared";
        public const string excode_default = "excode_default";
        //"CustomFunc() takes 1 or more argument(s)"
        public const string excode_customfunc_takes_1_or_more_argument = "excode_customfunc_takes_1_or_more_argument";
        //"'GenerateSSCC' function takes 1 parameter"
        public const string excode_generatesscc_function_takes_1_parameter = "excode_generatesscc_function_takes_1_parameter";
        //"'AddToDate' function takes 6 parameter"
        public const string excode_addtodate_function_takes_6_parameter = "excode_addtodate_function_takes_6_parameter";
        //"'Property' function takes only 1 parameter"
        public const string excode_property_function_takes_only_1_parameter = "excode_property_function_takes_only_1_parameter";
        //"'TimeStamp' function has no parameters"
        public const string excode_timestamp_function_has_no_parameters = "excode_timestamp_function_has_no_parameters";
        //"Argument '{0}' in method '{1}' has incorrect value";
        public const string excode_incorrect_argument = "excode_incorrect_argument";

        #endregion CODES

        public static string GetMessageByCode(string exCode)
        {
            if (StringHelper.IsVeryEmpty(exCode))
                return excode_default;
            
            FieldInfo fi = typeof(ExceptionHelper).GetField(exCode);
            if (fi == null)
                return excode_default;
            
            object oValue = fi.GetValue(null);
            if(oValue == null)
                return ExceptionHelper.excode_default;

            return oValue.ToString();
        }

        public static string GetFullExceptionInfo(Exception ex)
        {
            if (ex == null)
                return string.Empty;

            string result = String.Format("MESSAGE: {1}{0}STACK TRACE: {2}"
                , Environment.NewLine, ex.Message, ex.StackTrace);
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
                result += Environment.NewLine + Environment.NewLine
                    + String.Format("MESSAGE: {1}{0}STACK TRACE: {2}"
                        , Environment.NewLine, ex.Message, ex.StackTrace);
            }

            return result;
        }
                
        public static string GetFullExceptionMessage(Exception ex)
        {
            return GetFullExceptionMessage(ex, Environment.NewLine + "--> ");
        }

        public static string GetFullExceptionMessage(Exception ex, string separator)
        {
            if (ex == null)
                return String.Empty;

            string[] messages = GetExceptionMessages(ex);
            if (messages.Length < 1)
                return String.Empty;
            if (messages.Length < 2)
                return messages[0];
            string result = String.Join(separator, messages);

            return result;
        }

        public static string GetFullExceptionStackTrace(Exception ex)
        {
            return GetFullExceptionStackTrace(ex, Environment.NewLine + "--> ");
        }

        public static string GetFullExceptionStackTrace(Exception ex, string separator)
        {
            if (ex == null)
                return String.Empty;

            string result = ex.StackTrace;

            while (ex.InnerException != null)
            {
                result += String.Format("{0}{1}", separator, ex.InnerException.StackTrace);
                ex = ex.InnerException;
            }

            return result;
        }

        public static string[] GetExceptionMessages(Exception ex)
        {
            List<string> result = new List<string>();

            if (ex == null)
                return result.ToArray();

            result.Add(ex.Message);
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
                result.Add(ex.Message);
            }

            return result.ToArray();
        }

        public static string[] GetExceptionStackTraces(Exception ex)
        {
            List<string> result = new List<string>();

            if (ex == null)
                return result.ToArray();

            result.Add(ex.StackTrace);
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
                result.Add(ex.StackTrace);
            }

            return result.ToArray();
        }
    }
}
